#include "app_flash.h"

#include "main.h"
#include "app_debug_printf.h"

uint32_t flash_sector_base_addr[12] = {0x08000000, 0x08004000, 0x08008000,
									   0x0800c000, 0x08010000, 0x08020000,
									   0x08040000, 0x08060000, 0x08080000,
									   0x080a0000, 0x080c0000, 0x080e0000};

uint8_t flash_parta_erase(void)
{
	FLASH_EraseInitTypeDef erase_param = {.TypeErase = FLASH_TYPEERASE_SECTORS,
										  .Banks = FLASH_BANK_1,
										  .Sector = FLASH_PARTA_START_SECTOR,
										  .NbSectors = FLASH_PARTA_SECTOR_NUM,
										  .VoltageRange = FLASH_VOLTAGE_RANGE_3};

	uint32_t sector_error = 0;

	HAL_FLASH_Unlock();
	HAL_FLASHEx_Erase(&erase_param, &sector_error);
	HAL_FLASH_Lock();

	if (sector_error == 0xffffffff)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

void flash_program(uint32_t addr, const uint32_t *data, uint32_t len)
{
	HAL_StatusTypeDef retval;

	HAL_FLASH_Unlock();

	for (uint32_t i = 0; i < len; ++i)
	{
		retval = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,
								   addr + i * sizeof(uint32_t),
								   data[i]);
		assert_param(retval == HAL_OK);
	}

	HAL_FLASH_Lock();
}

void flash_rw_test(void)
{
	uint32_t buf[1024] = {0};
	for (uint32_t i = 0; i < sizeof(buf) / sizeof(buf[0]); ++i)
	{
		buf[i] = i;
	}

	if (!flash_parta_erase())
	{
		debug_printf("blocka_erase error\r\n");
	}

	for (uint32_t i = 0; i < sizeof(buf) / sizeof(buf[0]); ++i)
	{
		debug_printf("%u ",
					 *(volatile uint32_t *)(flash_sector_base_addr[FLASH_PARTA_START_SECTOR] + i * sizeof(uint32_t)));
	}
	debug_printf("\r\n");

	flash_program(flash_sector_base_addr[FLASH_PARTA_START_SECTOR], buf, sizeof(buf) / sizeof(buf[0]));

	for (uint32_t i = 0; i < sizeof(buf) / sizeof(buf[0]); ++i)
	{
		debug_printf("%u ",
					 *(volatile uint32_t *)(flash_sector_base_addr[FLASH_PARTA_START_SECTOR] + i * sizeof(uint32_t)));
	}
	debug_printf("\r\n");
}
